﻿using DrawRectangularCoordinateSystem;
using PedestrianSensingRadar.Area;
using PedestrianSensingRadar.MyCommon;
using PedestrianSensingRadar.Properties;
using PedestrianSensingRadar.Utility;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static PedestrianSensingRadar.CheckArea;

namespace PedestrianSensingRadar
{
    public partial class Frm_main : Form
    {
        // The main control for communicating through the RS-232 port
        private SerialPort comport = new SerialPort();
        //实例化数据解析工厂
        private DataparserFactory dataparserfactory = new DataparserFactory();
        private PedestrainArea pa = new PedestrainArea(new Rectangle(780, 100, 100, 100));//行人检测区
        private ZebraCheckArea za = new ZebraCheckArea(new Rectangle(795, 236, 70, 311));//斑马线检测区
        private GraphPainter m_graphPainter = new GraphPainter();//用于绘制坐标系
        private CanToolsHelper ToolsHelper = new CanToolsHelper();
        private Thread candataparse_thread;//CAN数据解析线程
        private Thread Display_thread;//雷达数据打点线程
        private Thread Record_thread;//雷达数据存储线程
        private Thread serdataparse_thread;//232数据解析线程
        public string filename;
        //static UInt32 m_devtype = 4;//USBCAN2
        UInt32 m_bOpen = 0;
        int is_record = 0;      
        UInt32[] m_arrdevtype = new UInt32[20];
        public static bool flag_org = false;
        public static int frameindex = 0;

        //20210304
        public Point firstpoint;
        public Point secondpoint;
        

        private int oldX;
        private int oldY;
        private int selCoilIndex = -1;
        private MouseActionType mouAction = MouseActionType.maNull;
        private PosSizableRect coilChangeobj = PosSizableRect.None;

        private delegate void setTextDelegate(string str);
   
        MessageCenter fromMC = null;
        public Frm_main()
        {
            InitializeComponent();
            
            MainClass.initCommon();
            InitializeControlValues();
            // When data is recieved through the port, call this method
            comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
        }

        private void setTxtJoker(string str)
        {
            lb_currentframe.Text = str;
            lb_currentframe.Update();
        }
        /// <summary> Populate the form's controls with default settings. </summary>
        private void InitializeControlValues()
        {
            cmbPortName.Items.Clear();
            foreach (string s in SerialPort.GetPortNames())
                cmbPortName.Items.Add(s);

            if (cmbPortName.Items.Contains(Settings.Default.PortName)) cmbPortName.Text = Settings.Default.PortName;
            else if (cmbPortName.Items.Count > 0) cmbPortName.SelectedIndex = 0;

            cmbcheckdir.SelectedIndex = 0;
            cmbBaudRate.SelectedIndex = 4;
        }
        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Packet_t packet;
            // Obtain the number of bytes waiting in the port's buffer
            packet.length = comport.BytesToRead;

            // Create a byte array buffer to hold the incoming data
            packet.pack = new byte[packet.length];

            // Read the data from the port and store it in our buffer
            comport.Read(packet.pack, 0, packet.length);
          
            Common.org_data_com.Enqueue(packet);                                      
        }

        //事件函数
        private void btn_opencan_Click(object sender, EventArgs e)
        {            
            if (m_bOpen == 1)
            {
                ToolsHelper.CloseCan();
                candataparse_thread.Abort();
                m_bOpen = 0;
            }
            else
            {
                int ret = ToolsHelper.OpenCan();
                if (ret == -1)
                {

                    MessageBox.Show("Open USBCAN Failed!", "ERROR",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else if (ret == -2)
                {
                    MessageBox.Show("USBCAN Init Failed!!", "ERROR"
                        , MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else if (ret == -3)
                {
                    MessageBox.Show("USBCAN Start Failed!", "ERROR"
                        , MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                m_bOpen = 1;
                             
            }  
            btn_opencan.Text = m_bOpen == 1 ? "关闭CAN" : "打开CAN";
            timer1.Enabled = m_bOpen == 1 ? true : false;

            //启动一个数据解析线程
            candataparse_thread = new Thread(CanObjTarget);
            candataparse_thread.Start();
            //启动打点线程
            Display_thread = new Thread(FramePlotter_Plot);
            Display_thread.Start();

        }
        private void btn_message_Click(object sender, EventArgs e)
        {
            if(comport.IsOpen)
                fromMC.Show();
            else
                MessageBox.Show("串口未打开！");
        }      
        private void pb_area_SizeChanged(object sender, EventArgs e)
        {
            using (Graphics g = this.CreateGraphics())
            {
                m_graphPainter.InitGraphPositions(g, pb_area.ClientSize);
            }
            Refresh();
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            ToolsHelper.CanDataReceive();
        }
        private void btn_record_Click(object sender, EventArgs e)
        {            
            string filename = DateTime.Now.ToString("yyyy-MMdd-HHmmss") + ".csv";
            this.filename = filename;
            
            if(is_record==1)
            {
                Record_thread.Abort();
                is_record = 0;                
            }
            else
            {
                is_record = 1;
                lb_filename.Text = filename;
                try
                {
                    FileStream file = new FileStream(filename, FileMode.Create,FileAccess.Write);
                    StreamWriter sw = new StreamWriter(file);
                    sw.WriteLine("frame,range,angle,speed,level,snr,timestamp");
                    sw.Close();
                                     
                    file.Close();
                }
                catch (IOException ex)
                {
                    MessageBox.Show(ex.Message, "ERROR",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }                
            }
            btn_record.Text = is_record == 1 ? "结束记录" : "开始记录";
            Record_thread = new Thread(CsvRecord);
            Record_thread.Start();
        }
        private void btn_rebuild_Click(object sender, EventArgs e)
        {
            Common.areas.Clear();
            pb_area.Refresh();
        }
        private void btnaddarea_Click(object sender, EventArgs e)
        {
            //1 根据用户选择在界面添加默认检测区
            if (rb_xr.Checked)
            {
                pa.mPictureBox = pb_area;
                pa.areaNum = 0x01;
                //pa.Draw(Common.gra);
                Common.areas.Add(pa);
                pb_area.Refresh();
            }
            else if (rb_bm.Checked)
            {
                za.mPictureBox = pb_area;
                za.areaNum = 0x02;
                //pa.Draw(Common.gra);
                Common.areas.Add(za);
                pb_area.Refresh();
            }

            //2 检测区域要求可以移动，放大和缩小
        }
        private void pb_area_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Matrix oldmx = g.Transform;
            m_graphPainter.DrawCoordinate(g, pb_area.ClientSize);
            g.Transform = oldmx;

            for (int i = 0; i < Common.areas.Count; i++)
            {
                Common.areas[i].Draw(g);
            }
        }
        private void Frm_main_FormClosing(object sender, FormClosingEventArgs e)
        {
            comport.Close();
            //ser.m_OpenCom = 0;
            if (serdataparse_thread != null)
                serdataparse_thread.Abort();
            if (Display_thread != null)
                Display_thread.Abort();
        }
        public enum MouseActionType { maMoveCoil, maChaneSizeCoil, maMoveLane, maNull };//鼠标事件类型
        private void pb_area_MouseDown(object sender, MouseEventArgs e)
        {
           if(e.Button==MouseButtons.Left)//鼠标左键按下
           {
                for(int i=0;i<Common.areas.Count;i++)
                {
                    if(Common.areas[i].rect.Contains(e.Location))
                    {
                        selCoilIndex = i;
                        mouAction = MouseActionType.maMoveCoil;
                        return;
                    }
                    Common.areas[i].ChangeCursor(e.Location);
                    coilChangeobj = Common.areas[i].nodeSelected;
                    if (coilChangeobj != PosSizableRect.None)
                    {
                        selCoilIndex = i;
                        mouAction = MouseActionType.maChaneSizeCoil;
                        return;
                    }
                }
                oldX = e.X;
                oldY = e.Y;
            }
        }//鼠标按下
        private void pb_area_MouseMove(object sender, MouseEventArgs e)//鼠标移动
        {         
            switch (mouAction)
            {
                case MouseActionType.maMoveCoil://移动检测线圈
                    {
                        CheckArea area = Common.areas[selCoilIndex];
                        area.rect.X += e.X - oldX;
                        area.rect.Y += e.Y - oldY;
                    }
                    break;
                case MouseActionType.maChaneSizeCoil://改变线圈大小
                    {
                        CheckArea area = Common.areas[selCoilIndex];
                        switch (area.nodeSelected)
                        {
                            case PosSizableRect.LeftUp:
                                area.rect.X += e.X - oldX;
                                area.rect.Width -= e.X - oldX;
                                area.rect.Y += e.Y - oldY;
                                area.rect.Height -= e.Y - oldY;
                                break;

                            case PosSizableRect.LeftMiddle:
                                area.rect.X += e.X - oldX;
                                area.rect.Width -= e.X - oldX;
                                break;
                            case PosSizableRect.LeftBottom:
                                area.rect.Width -= e.X - oldX;
                                area.rect.X += e.X - oldX;
                                area.rect.Height += e.Y - oldY;
                                break;
                            case PosSizableRect.BottomMiddle:
                                area.rect.Height += e.Y - oldY;
                                break;
                            case PosSizableRect.RightUp:
                                area.rect.Width += e.X - oldX;
                                area.rect.Y += e.Y - oldY;
                                area.rect.Height -= e.Y - oldY;
                                break;
                            case PosSizableRect.RightBottom:
                                area.rect.Width += e.X - oldX;
                                area.rect.Height += e.Y - oldY;
                                break;
                            case PosSizableRect.RightMiddle:
                                area.rect.Width += e.X - oldX;
                                break;
                            case PosSizableRect.UpMiddle:
                                area.rect.Y += e.Y - oldY;
                                area.rect.Height -= e.Y - oldY;
                                break;
                        }
                    }
                break;
            }
            oldX = e.X;//更新位置
            oldY = e.Y;
            if(mouAction== MouseActionType.maMoveCoil|| mouAction == MouseActionType.maChaneSizeCoil)
                pb_area.Refresh();//导致触发pb_areaPaint            
        }
        private void pb_area_MouseUp(object sender, MouseEventArgs e)//鼠标弹起
        {
            mouAction = MouseActionType.maNull;
            pb_area.Cursor= Cursors.Default;
        }
        private void btn_openserial_Click(object sender, EventArgs e)
        {
            //实例化串口数据解析器
            SerDataparser ser = (SerDataparser)dataparserfactory.GetDataparser(0);
            ser.showareastate += Ser_showareastate;
            fromMC= MessageCenter.GetInstance(ser);

            // If the port is open, close it.
            if (comport.IsOpen)
            {
                comport.Close();
                ser.m_OpenCom = 0;
                Common.state_machine = 0;
                serdataparse_thread.Abort();
                Display_thread.Abort();
            }               
            else
            {
                // Set the port's settings
                comport.BaudRate =  int.Parse(cmbBaudRate.Text);
                comport.DataBits = 8;
                comport.StopBits = StopBits.One;
                comport.Parity = 0;
                comport.PortName = cmbPortName.Text;

                try
                {
                    // Open the port
                    comport.Open();
                    ser.m_OpenCom = 1;

                    Common.is_sigal = fromMC.Getcb_sigalchecked;
                    Common.isobj = fromMC.Cb_objchecked;

                    //fromMC.Show();

                    serdataparse_thread = new Thread(ser.SerObjTarget);
                    serdataparse_thread.Start();

                    //启动打点线程
                    Display_thread = new Thread(FramePlotter_Plot);
                    Display_thread.Start();
                }
                catch(Exception ex)
                {
                    MessageBox.Show("错误：" + ex.Message, "");
                }
            }
            btn_openserial.Text = ser.m_OpenCom == 1 ? "关闭串口" : "打开串口";         
        }

        private void Ser_showareastate(byte[] areadata)
        {
            Action act=delegate()
            {
                lb_xr_state.Text = areadata[0].ToString();
                lb_xr_num.Text = areadata[1].ToString();
                lb_bm_state.Text = areadata[2].ToString();
                lb_bm_num.Text = areadata[3].ToString();
            };
            Invoke(act);
        }

        //参数下发行人感知雷达
        private void btn_write_Click(object sender, EventArgs e)
        {
            if (comport.IsOpen && Restrain.IsInputEmpyt(cmbcheckdir.Text) != 0&&Common.areas.Count==2)
                SendSerData(Common.areas);
            else if (!comport.IsOpen)
                MessageBox.Show("串口未打开！");
            else if(Common.areas.Count <2)
                MessageBox.Show("请先设置好检测区域！");
            else
                MessageBox.Show("检测方向和区域编号不可为空！");
        }

        /// <summary>
        /// 像素转换为长度(实际长度需要除10)
        /// </summary>
        /// <param name="painter"></param>
        /// <param name="pointF"></param>
        /// <returns></returns>
        private PointF PixeltoLength(GraphPainter painter,ref PointF pointF)
        {
            pointF.X= (float)Math.Round((pointF.X - painter.Coordinate.OriginPoint.X) / painter.Coordinate.XAxesDecision,1);
            pointF.Y= (float)Math.Round((painter.Coordinate.OriginPoint.Y - pointF.Y) / painter.Coordinate.YAxesDecision,1);
            pointF.X = pointF.X * 10;
            pointF.Y = pointF.Y * 10;
            return pointF;
        }

        private void SendSerData(List<CheckArea> checkAreas)
        {
            float Hori_angle, Pitch_angle, Height;
            //byte Height;

            Hori_angle = (float)Math.Round(float.Parse(tb_hori.Text),1)*10;
            Pitch_angle = (float)Math.Round(float.Parse(tb_pitch.Text),1)*10;
            Height = (float)Math.Round(float.Parse(tb_H.Text),1)*10;

            List<byte> datalst = new List<byte>();

            checkAreas[0].p1.X = checkAreas[0].rect.X;
            checkAreas[0].p1.Y = checkAreas[0].rect.Y;

            checkAreas[0].p4.X = checkAreas[0].rect.X + checkAreas[0].rect.Width;
            checkAreas[0].p4.Y = checkAreas[0].rect.Y + checkAreas[0].rect.Height;


            //严格按照从上到下，从左到右标记P1,P2,P3,P4；避免雷达数据映射混乱
            PointF p1 = new PointF(checkAreas[0].p1.X, checkAreas[0].p1.Y);
            PointF p4 = new PointF(checkAreas[0].p4.X, checkAreas[0].p4.Y);

            PointF p3=new PointF();
            PointF p2 = new PointF();
            p2.X = checkAreas[0].p4.X;
            p2.Y = checkAreas[0].p1.Y;
            p3.X = checkAreas[0].p1.X;
            p3.Y = checkAreas[0].p4.Y;
            
            PixeltoLength(m_graphPainter, ref p1);
            PixeltoLength(m_graphPainter, ref p2);
            PixeltoLength(m_graphPainter, ref p3);
            PixeltoLength(m_graphPainter, ref p4);

            byte[] b_Hori_angle = new byte[2];
            byte[] b_Pitch_angle = new byte[2];
                
            byte[] b_p1_x=new byte[2];
            byte[] b_p1_y = new byte[2];

            byte[] b_p2_x = new byte[2];
            byte[] b_p2_y = new byte[2];

            byte[] b_p3_x = new byte[2];
            byte[] b_p3_y = new byte[2];

            byte[] b_p4_x = new byte[2];
            byte[] b_p4_y = new byte[2];

            b_Hori_angle = BitConverter.GetBytes((short)Hori_angle);
            b_Pitch_angle = BitConverter.GetBytes((short)Pitch_angle);

            b_p1_x =BitConverter.GetBytes((short)p1.X);
            b_p1_y= BitConverter.GetBytes((short)p1.Y);

            b_p2_x = BitConverter.GetBytes((short)p2.X);
            b_p2_y = BitConverter.GetBytes((short)p2.Y);

            b_p3_x = BitConverter.GetBytes((short)p3.X);
            b_p3_y = BitConverter.GetBytes((short)p3.Y);

            b_p4_x = BitConverter.GetBytes((short)p4.X);
            b_p4_y = BitConverter.GetBytes((short)p4.Y);

            switch (cmbcheckdir.Text)
            {
                case "东":
                    Common.linkflag = 0x0F;
                    break;
                case "南":
                    Common.linkflag = 0x17;
                    break;
                case "西":
                    Common.linkflag = 0x1F;
                    break;
                case "北":
                    Common.linkflag = 0x07;
                    break;
                case "东北":
                    Common.linkflag = 0x0B;
                    break;
                case "东南":
                    Common.linkflag = 0x13;
                    break;
                case "西南":
                    Common.linkflag = 0x1B;
                    break;
                case "西北":
                    Common.linkflag = 0x23;
                    break;
                default:
                    //MessageBox.Show("检测方向信息错误！");
                    break;
            }
            //到此第一个区域的数据已经全部获得

            checkAreas[1].p1.X = checkAreas[1].rect.X;
            checkAreas[1].p1.Y = checkAreas[1].rect.Y;

            checkAreas[1].p4.X = checkAreas[1].rect.X + checkAreas[1].rect.Width;
            checkAreas[1].p4.Y = checkAreas[1].rect.Y + checkAreas[1].rect.Height;//由于GDI坐标的特殊性，此为+

            PointF p5 = new PointF(checkAreas[1].p1.X, checkAreas[1].p1.Y);
            PointF p8 = new PointF(checkAreas[1].p4.X, checkAreas[1].p4.Y);

            PointF p7 = new PointF();
            PointF p6 = new PointF();
            p6.X = checkAreas[1].p4.X;
            p6.Y = checkAreas[1].p1.Y;
            p7.X = checkAreas[1].p1.X;
            p7.Y = checkAreas[1].p4.Y;

            PixeltoLength(m_graphPainter, ref p5);
            PixeltoLength(m_graphPainter, ref p6);
            PixeltoLength(m_graphPainter, ref p7);
            PixeltoLength(m_graphPainter, ref p8);

           

            byte[] b_p5_x = new byte[2];
            byte[] b_p5_y = new byte[2];

            byte[] b_p6_x = new byte[2];
            byte[] b_p6_y = new byte[2];

            byte[] b_p7_x = new byte[2];
            byte[] b_p7_y = new byte[2];

            byte[] b_p8_x = new byte[2];
            byte[] b_p8_y = new byte[2];

       

            b_p5_x = BitConverter.GetBytes((short)p5.X);
            b_p5_y = BitConverter.GetBytes((short)p5.Y);

            b_p6_x = BitConverter.GetBytes((short)p6.X);
            b_p6_y = BitConverter.GetBytes((short)p6.Y);

            b_p7_x = BitConverter.GetBytes((short)p7.X);
            b_p7_y = BitConverter.GetBytes((short)p7.Y);

            b_p8_x = BitConverter.GetBytes((short)p8.X);
            b_p8_y = BitConverter.GetBytes((short)p8.Y);

            //到此第二个区域数据全部获得

            //计算校验和
            byte checksum = 0;

            byte[] tmpdata = { Common.linkflag, 0x21,0x87,0x7B,checkAreas[0].areaNum,
                                b_Hori_angle[0],b_Hori_angle[1],b_Pitch_angle[0],b_Pitch_angle[1],(byte)Height,
                                b_p1_x[0],b_p1_x[1],b_p1_y[0],b_p1_y[1],
                                b_p2_x[0],b_p2_x[1],b_p2_y[0],b_p2_y[1],
                                b_p3_x[0],b_p3_x[1],b_p3_y[0],b_p3_y[1],
                                b_p4_x[0],b_p4_x[1],b_p4_y[0],b_p4_y[1],
                                checkAreas[1].areaNum,
                                b_p5_x[0],b_p5_x[1],b_p5_y[0],b_p5_y[1],
                                b_p6_x[0],b_p6_x[1],b_p6_y[0],b_p6_y[1],
                                b_p7_x[0],b_p7_x[1],b_p7_y[0],b_p7_y[1],
                                b_p8_x[0],b_p8_x[1],b_p8_y[0],b_p8_y[1],
                            };

                
            for (int j = 0; j < tmpdata.Length; j++)
            {
                checksum ^= tmpdata[j];
            }

            if (checksum == 0x7E)
            {
                byte[] data = {0x7E, Common.linkflag, 0x21,0x87,0x7B, checkAreas[0].areaNum,
                        b_Hori_angle[0],b_Hori_angle[1],b_Pitch_angle[0],b_Pitch_angle[1],(byte)Height,
                        b_p1_x[0],b_p1_x[1],b_p1_y[0],b_p1_y[1],
                        b_p2_x[0],b_p2_x[1],b_p2_y[0],b_p2_y[1],
                        b_p3_x[0],b_p3_x[1],b_p3_y[0],b_p3_y[1],
                        b_p4_x[0],b_p4_x[1],b_p4_y[0],b_p4_y[1],
                        checkAreas[1].areaNum,
                        b_p5_x[0],b_p5_x[1],b_p5_y[0],b_p5_y[1],
                        b_p6_x[0],b_p6_x[1],b_p6_y[0],b_p6_y[1],
                        b_p7_x[0],b_p7_x[1],b_p7_y[0],b_p7_y[1],
                        b_p8_x[0],b_p8_x[1],b_p8_y[0],b_p8_y[1],
                        0x7D,0x5E ,0x7E};
                comport.Write(data, 0, data.Length);
                if (fromMC != null)
                {
                    fromMC.Frmmain_showsendEvent(data);
                    fromMC.dataParseTest(data);
                }
            }
            else if (checksum == 0x7D)
            {
                byte[] data = {0x7E, Common.linkflag, 0x21,0x87,0x7B, checkAreas[0].areaNum,
                        b_Hori_angle[0],b_Hori_angle[1],b_Pitch_angle[0],b_Pitch_angle[1],(byte)Height,
                        b_p1_x[0],b_p1_x[1],b_p1_y[0],b_p1_y[1],
                        b_p2_x[0],b_p2_x[1],b_p2_y[0],b_p2_y[1],
                        b_p3_x[0],b_p3_x[1],b_p3_y[0],b_p3_y[1],
                        b_p4_x[0],b_p4_x[1],b_p4_y[0],b_p4_y[1],
                        checkAreas[1].areaNum,
                        b_p5_x[0],b_p5_x[1],b_p5_y[0],b_p5_y[1],
                        b_p6_x[0],b_p6_x[1],b_p6_y[0],b_p6_y[1],
                        b_p7_x[0],b_p7_x[1],b_p7_y[0],b_p7_y[1],
                        b_p8_x[0],b_p8_x[1],b_p8_y[0],b_p8_y[1],
                        0x7D,0x5D ,0x7E};
                comport.Write(data, 0, data.Length);
                if (fromMC != null)
                {
                    fromMC.Frmmain_showsendEvent(data);
                    fromMC.dataParseTest(data);
                }
            }
            else
            {
                byte[] data = {0x7E, Common.linkflag, 0x21,0x87,0x7B, checkAreas[0].areaNum,
                        b_Hori_angle[0],b_Hori_angle[1],b_Pitch_angle[0],b_Pitch_angle[1],(byte)Height,
                        b_p1_x[0],b_p1_x[1],b_p1_y[0],b_p1_y[1],
                        b_p2_x[0],b_p2_x[1],b_p2_y[0],b_p2_y[1],
                        b_p3_x[0],b_p3_x[1],b_p3_y[0],b_p3_y[1],
                        b_p4_x[0],b_p4_x[1],b_p4_y[0],b_p4_y[1],
                        checkAreas[1].areaNum,
                        b_p5_x[0],b_p5_x[1],b_p5_y[0],b_p5_y[1],
                        b_p6_x[0],b_p6_x[1],b_p6_y[0],b_p6_y[1],
                        b_p7_x[0],b_p7_x[1],b_p7_y[0],b_p7_y[1],
                        b_p8_x[0],b_p8_x[1],b_p8_y[0],b_p8_y[1],
                        checksum ,0x7E};

                comport.Write(data, 0, data.Length);
                if (fromMC != null)
                {
                    fromMC.Frmmain_showsendEvent(data);
                    fromMC.dataParseTest(data);
                }
            }
         }        
  
          
        /// <summary>
        /// 雷达数据解析线程
        /// </summary>
        public void CanObjTarget()
        {
            Frame_t frame = new Frame_t();//new一个帧对象           
            frame.lstTargets.Clear();
            
            while (m_bOpen == 1)
            {
                VCI_CAN_OBJ obj;
                if (Common.org_data.TryDequeue(out obj))
                {
                    if (flag_org)
                    {
                        if (obj.ID == 0x503)
                        {
                            Target_t target = new Target_t();//new一个目标点
                            CanObj2Target(ref target, obj,frameindex);
                            frame.lstTargets.Add(target);
                        }
                        else if (obj.ID == 0x501)
                        {
                            //完成一帧                                                      
                            Common.frame.Enqueue(frame);
                            Common.frame_record.Enqueue(frame);
                            frame = new Frame_t();
                            //新帧处理

                            flag_org = true;
                        }
                    }
                    if (obj.ID == 0x501)
                    {
                        //新帧处理
                        //frameindex++;
                        flag_org = true;
                    }
                }
            }
        }
        //截取can数据
        public UInt16 GetCanMsg(String msg, int start_pos, int length)
        {
            return System.Convert.ToUInt16(msg.Substring(start_pos, length), 2);
        }

        //目标数据解析
        unsafe public void CanObj2Target(ref Target_t targetout, VCI_CAN_OBJ obj,int index)
        {
            String obj_str = "";

            for (int i = 0; i < 8; i++)
            {
                obj_str += System.Convert.ToString(obj.Data[i], 2).PadLeft(8, '0');
            }

            targetout.id = GetCanMsg(obj_str, 0, 8);
            targetout.frame = index;
            targetout.range = GetCanMsg(obj_str, 8, 12) * 0.1f;
            targetout.speed = GetCanMsg(obj_str, 21, 11) * 0.1f - 102.4f;
            targetout.angle = GetCanMsg(obj_str, 33, 11) * 0.1f - 102.4f;
            targetout.level = GetCanMsg(obj_str, 48, 8) * 0.5f - 64.0f;
            targetout.snr = GetCanMsg(obj_str, 56, 8);
        }
        /// <summary>
        /// 主界面打点
        /// </summary>
        public void FramePlotter_Plot()
        {            
            Graphics g= pb_area.CreateGraphics();          
            Frame_t frame_T=new Frame_t();            
            while (true)
            {
                Common.frame.TryDequeue(out frame_T);
              
                if (frame_T != null)
                {
                    if (cb_autorefresh.Checked)
                    {
                        Action act = delegate ()
                        {
                            pb_area.Refresh();
                        };
                        Invoke(act);
                        //g.Clear(Color.Transparent);
                    }
                    lb_currentframe.BeginInvoke(new setTextDelegate(setTxtJoker),frame_T.frame_serial.ToString());//利用委托更新UI控件

                    for (int i = 0; i < frame_T.lstTargets.Count; ++i)
                    {
                        double angle = frame_T.lstTargets[i].angle * 3.14 / 180.0;
                        double range = frame_T.lstTargets[i].range;

                        double x = range * Math.Sin(angle) * m_graphPainter.Coordinate.XAxesDecision;
                        double y = range * Math.Cos(angle) * m_graphPainter.Coordinate.YAxesDecision;

                        if(Math.Abs(x)>0|| Math.Abs(y) > 0)
                            g.FillRectangle(Brushes.Red, m_graphPainter.Coordinate.OriginPoint.X+(float)x, m_graphPainter.Coordinate.OriginPoint.Y - (float)y, 8, 8);                       
                    }
                }
                //Thread.Sleep(1);
            }
            
        }   
        /// <summary>
        /// 数据存储线程回调函数
        /// </summary>
        public void CsvRecord()
        {
            int newlineflag = 0;
            string line = "";            
            Frame_t frame_T = new Frame_t();
            while (is_record==1)
            {
                if (Common.frame_record.TryDequeue(out frame_T))
                {              
                    for (int i = 0; i < frame_T.lstTargets.Count; ++i)
                    {
                        if (Math.Abs(frame_T.lstTargets[i].speed) > 0)
                        {
                            line = frame_T.frame_serial.ToString() + "," +
                                frame_T.lstTargets[i].range.ToString() + "," +
                                frame_T.lstTargets[i].angle.ToString() + "," +
                                frame_T.lstTargets[i].speed.ToString() + "," +
                                frame_T.lstTargets[i].level.ToString() + "," +
                                frame_T.lstTargets[i].snr.ToString() + "," +
                                DateTime.Now.ToString("yyyy-MMdd-HH:mm:ss-ffff") + "\n";

                            File.AppendAllText(filename, line);
                            newlineflag = 1;
                        }
                    }
                    if (newlineflag == 1)
                    {
                        File.AppendAllText(this.filename, "\n");
                        newlineflag = 0;
                    }
                }
                else
                {
                    Thread.Sleep(10);
                }
            }
        }

        private void timer_autorefresh_Tick(object sender, EventArgs e)
        {
            pb_area.Refresh();
        }

        private void cb_autorefresh_CheckedChanged(object sender, EventArgs e)
        {
            //timer_autorefresh.Enabled = cb_autorefresh.Checked == true ? true : false;
        }

    
    }   
}
